﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Big2.CardsLib
{
    public class CardHelper
    {
        public CardHelper() { }

        //Method to sort the cards in either ascending or decsending order
        //depending on the boolean value if is true then is asc if false is desc
        //the sorting algorithm is insertion sort which creates a new temp list of cards 
        //and adds it to it and returns that newly constructed deck.
        //Needs to sort suit as well as the rank from ace of diamonds to king of spades.

        public static List<Card> SortCards(List<Card> list, bool order)
        {
            if (list == null || list.Count == 0 || list.Count == 1)
                throw new Exception("List is empty");

            //make ace and 2 = value of 14 & 15
            ChangeValue(list, true);

            List<Card> TempList = new List<Card>();
            int mover = 0;

            Card NextCardToInsert = list.ElementAt(0);
            TempList.Add(NextCardToInsert);
            list.RemoveAt(0);

            while (list.Count != 0)
            {
                NextCardToInsert = list.ElementAt(0);

                for (mover = 0; mover < TempList.Count; mover++)
                {
                    if (NextCardToInsert.Value < TempList.ElementAt(mover).Value)         //if less than
                    {
                        TempList.Insert(mover, NextCardToInsert);
                        break;
                    }//if
                    else if ((NextCardToInsert.Value > TempList.ElementAt(mover).Value) && (mover + 1 >= TempList.Count))
                    {
                        TempList.Add(NextCardToInsert);
                        break;
                    }//else if
                    else if (NextCardToInsert.Value == TempList.ElementAt(mover).Value)
                    {
                        if (NextCardToInsert.Suit < TempList.ElementAt(mover).Suit)
                        {
                            TempList.Insert(mover, NextCardToInsert);
                            break;
                        }//if
                        else
                        {
                            if (mover + 1 < TempList.Count)
                            {
                                if (TempList.ElementAt(mover + 1).isSameValue(NextCardToInsert))
                                    continue;
                            }//if
                            else
                            {
                                TempList.Add(NextCardToInsert);
                                break;
                            }//else 
                        }//outer else
                    }//outer else if
                }//for

                list.RemoveAt(0); 
            }//while

            ChangeValue(TempList, false);

            if (!order)
                TempList.Reverse();

            return TempList;
        }//List<Card> SortCards(List<Card> list, bool order)

        public static void ChangeValue(List<Card> list, bool first)
        {
            if (first)
            {
                for (int i = 0; i < list.Count; i++)
                {
                    if (list.ElementAt(i).Value == 1)
                        list.ElementAt(i).Value = 14;
                    else if (list.ElementAt(i).Value == 2)
                        list.ElementAt(i).Value = 15;
                }
            }
            else
            {
                for (int i = 0; i < list.Count; i++)
                {
                    if (list.ElementAt(i).Value == 14)
                        list.ElementAt(i).Value = 1;
                    else if (list.ElementAt(i).Value == 15)
                        list.ElementAt(i).Value = 2;
                }
            }
        }//void ChangeValue(List<Card> list, bool first)

        /*
        This is an additional method of sorting -- helper to sort without any modification
        */
        public static List<Card> TempSortCards(List<Card> list, bool order)
        {
            if (list == null || list.Count == 0 || list.Count == 1)
                throw new Exception("List is empty");

            List<Card> TempList = new List<Card>();
            int mover = 0;

            Card NextCardToInsert = list.ElementAt(0);
            TempList.Add(NextCardToInsert);
            list.RemoveAt(0);

            while (list.Count != 0)
            {
                NextCardToInsert = list.ElementAt(0);

                for (mover = 0; mover < TempList.Count; mover++)
                {
                    if (NextCardToInsert.Value < TempList.ElementAt(mover).Value)         //if less than
                    {
                        TempList.Insert(mover, NextCardToInsert);
                        break;
                    }//if
                    else if ((NextCardToInsert.Value > TempList.ElementAt(mover).Value) && (mover + 1 >= TempList.Count))
                    {
                        TempList.Add(NextCardToInsert);
                        break;
                    }//else if
                    else if (NextCardToInsert.Value == TempList.ElementAt(mover).Value)
                    {
                        if (NextCardToInsert.Suit < TempList.ElementAt(mover).Suit)
                        {
                            TempList.Insert(mover, NextCardToInsert);
                            break;
                        }//if
                        else
                        {
                            if (mover + 1 < TempList.Count)
                            {
                                if (TempList.ElementAt(mover + 1).isSameValue(NextCardToInsert))
                                    continue;
                            }//if
                            else
                            {
                                TempList.Add(NextCardToInsert);
                                break;
                            }//else 
                        }//outer else
                    }//outer else if
                }//for

                list.RemoveAt(0);
            }//while
            if (!order)
                TempList.Reverse();

            return TempList;
        }//List<Card> SortCards(List<Card> list, bool order)



        /*
        public static List<Card> SortCards(List<Card> list, bool order)
        {
            if(list == null || list.Count == 0)
                throw new Exception("List is empty");

            List<Card> TempList = new List<Card>();
            int numOfDiamonds = AmtOf(list, CardSuit.Diamonds);
            int numOfClubs = AmtOf(list, CardSuit.Clubs);
            int numOfHearts = AmtOf(list, CardSuit.Hearts);
            int numOfSpades = AmtOf(list, CardSuit.Spades);

            SortSuit(list, TempList, CardSuit.Diamonds, numOfDiamonds);
            SortSuit(list, TempList, CardSuit.Clubs, numOfClubs);
            SortSuit(list, TempList, CardSuit.Hearts, numOfHearts);
            SortSuit(list, TempList, CardSuit.Spades, numOfSpades);

            return TempList;
        }//List<Cards> SortCards(List<Cards> list, bool order)

        //sort through each suit in ascending order
        public static void SortSuit(List<Card> realList, List<Card> tempList, CardSuit suit, int count)
        {
            Card lowest = null;
            int i = 0;
            int point = 0;

            while (count != 0)
            {
                for (i = 0; i < realList.Count(); i++)
                {
                    if (realList.ElementAt(i).Suit == suit)
                    {
                        if (lowest == null)         //first occurence
                        {
                            lowest = new Card();
                            lowest = realList.ElementAt(i);
                            point = i;
                        }//if
                        else
                        {
                            if (realList.ElementAt(i).Value < lowest.Value)
                            {
                                lowest = realList.ElementAt(i);
                                point = i;
                            }//if
                        }//else

                    }//outerif
                }//for

                tempList.Add(lowest);
                realList.RemoveAt(point);
                --count;
                lowest = null;
                point = 0;
            }//while

        }//void SortSuit(List<Card> holdingList, CardSuit suit)

        //get the amount of occurences of each suit in the list
        public static int AmtOf(List<Card> list, CardSuit suit)
        {
            int count = 0;

            for (int i = 0; i < list.Count(); i++)
            {
                if (list.ElementAt(i).Suit == suit)
                    ++count;
            }//for

            return count;
        }//int AmtOf(List<Card> list, CardSuit suit)

        */
        //#endregion

        public static void RemoveCards(List<Card> cards, List<Card> cToRemove)
        {
            foreach (Card card in cToRemove)
                RemoveCards(cards, card);
        }
        public static void RemoveCards(List<Card> cards, Card cToRemove)
        {
            foreach (Card c in cards)
                if (cToRemove.isSameCard(c))
                {
                    cards.Remove(c);
                    return;
                }
        }
        
    }
}
